package com.googlecode.continuity.core.client;

import java.util.HashMap;
import java.util.Map;
import java.io.Serializable;

import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * Super class for any enumeration used.  Provides the possiblity to easily persist enumerations
 * (and objects having them as a field) with Hibernate but doesn't depend on that framework.
 * Source and more information from: http://www.hibernate.org/288.html, originally written by saket_ag.
 * <p/>
 * Values of enum instances MUST be distinct.
 *
 * todo: this is seriously broken: enum's with a common name overwrite each other, the same is true for values - use java Enums instead
 *
 * @author Peter Schmitt <aragos@aragos.de>
 */
public abstract class Enum implements IsSerializable {
// ------------------------------ FIELDS ------------------------------

  protected static Map nameMap = new HashMap(15);
  protected static Map valueMap = new HashMap(15);
  protected int value;
  protected String name;

// -------------------------- STATIC METHODS --------------------------

  /**
   * Returns the <code>Enum</code> object with the given name.
   *
   * @param name enum object's name
   * @return enum object with the given name
   */
  public static Enum get(String name) {
    return (Enum) nameMap.get(name);
  }

  /**
   * Returns the <code>Enum</code> object with the given value.
   * @param value the enum's value
   * @return enum with the given value
   */
  public static Enum get(int value) {
    return (Enum) valueMap.get(new Integer(value));
  }

// --------------------------- CONSTRUCTORS ---------------------------

  /**
   * Constructs a new <code>Enum</code> instance and adds it to the internal enum maps.
   *
   * @param name enum's name
   * @param value enum's value
   */
  protected Enum(String name, int value) {
    this.value = value;
    this.name = name;
    if (name != null) {
      add();
    }
  }

  /**
   * Adds this object to the internal enum maps.
   */
  protected void add() {
    nameMap.put(this.name, this);
    valueMap.put(new Integer(this.value), this);
  }

// --------------------- GETTER / SETTER METHODS ---------------------

  /**
   * Returns this enum object's name.
   *
   * @return this enum's name
   */
  public String getName() {
    return name;
  }

  /**
   * REturn this enum object's value.
   *
   * @return this enum's value
   */
  public int getValue() {
    return value;
  }
}
